package com.meisupic.copyright.support.security;

import com.meisupic.copyright.util.StringUtil;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.NullRememberMeServices;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * @author lanjian
 * @version V1.0
 * @Description: TODO
 * @date 2018/4/29 20:29
 */
public class SSOFliter extends AbstractAuthenticationProcessingFilter {

  private RememberMeServices rememberMeServices = new NullRememberMeServices();

  private boolean continueChainBeforeSuccessfulAuthentication = false;

  private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();

  public SSOFliter() {
    super(new AntPathRequestMatcher("/**"));
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
      HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
    String sid = "";
    Authentication authentication = null;
    if (request.getCookies() != null) {
      for (Cookie cookie : request.getCookies()) {
        if ("sid".equals(cookie.getName())) {
          sid = URLDecoder.decode(cookie.getValue());
        }
      }
      if (!StringUtil.isEmpty(sid)) {
        HuabanLoginAuthenticationToken authenticationToken = new HuabanLoginAuthenticationToken(sid,
            null);
        authentication = this.getAuthenticationManager()
            .authenticate(authenticationToken);
      }
    }
    return authentication;
  }


  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    Authentication authResult;

    try {
      authResult = attemptAuthentication(request, response);
      if (authResult == null) {
        chain.doFilter(request, response);
        return;
      }
      sessionStrategy.onAuthentication(authResult, request, response);
    } catch (InternalAuthenticationServiceException failed) {
      chain.doFilter(request, response);
      return;
    } catch (AuthenticationException failed) {
      chain.doFilter(request, response);
      return;
    }
    // Authentication success
    if (continueChainBeforeSuccessfulAuthentication) {
      chain.doFilter(request, response);
    }
    SecurityContextHolder.getContext().setAuthentication(authResult);

    rememberMeServices.loginSuccess(request, response, authResult);

    // Fire event
    if (this.eventPublisher != null) {
      eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
          authResult, this.getClass()));
    }
    chain.doFilter(request, response);
  }

}
